package com.cxs.videoplayer.controller;

import com.cxs.videoplayer.ResourceTable;
import com.cxs.videoplayer.api.StatusChangeListener;
import com.cxs.videoplayer.constant.Constants;
import com.cxs.videoplayer.constant.PlayerStatus;
import com.cxs.videoplayer.play.MPlayer;
import ohos.agp.components.*;
import ohos.agp.components.surfaceprovider.SurfaceProvider;
import ohos.agp.graphics.Surface;
import ohos.app.Context;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.eventhandler.InnerEvent;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;

import java.util.List;

import static com.cxs.videoplayer.constant.Constants.*;

public class PlayerController extends ComponentContainer {
    static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00101, "PlayerController");
    private Context context;
    private MPlayer mPlayer;    // 自定义播放器类
    SurfaceProvider surfaceView;
    Surface surface;
    private ControllerHandler controllerHandler;
    private Button btnPlay, btnPause, btnPrevious, btnNext;
    private Text textPosition, textDuration, textTitle;
    private Slider progress = null;   // 进度条
    private DirectionalLayout videoLayout;    // 播放窗口
    private List<String> playList;
    private int playIndex = 0;

    public PlayerController(Context context, MPlayer mPlayer, List<String> playList) {
        super(context);
        this.context = context;
        this.mPlayer = mPlayer;
        this.playList = playList;
        for (String list : playList) {
            HiLog.info(LABEL, list);
        }
        initComponent();
        createHandler();
    }

    void initComponent() {
        Component controllerLayout = LayoutScatter.getInstance(context)
                .parse(ResourceTable.Layout_player_controller_layout, null, false);
        addComponent(controllerLayout);
        Component cptProgress = controllerLayout.findComponentById(ResourceTable.Id_progress);
        if (cptProgress instanceof Slider) {
            progress = (Slider) cptProgress;
        }
        Component cptPlay = controllerLayout.findComponentById(ResourceTable.Id_btn_play);
        if (cptPlay instanceof Button) {
            btnPlay = (Button) cptPlay;
        }
        Component cptPause = controllerLayout.findComponentById(ResourceTable.Id_btn_pause);
        if (cptPause instanceof Button) {
            btnPause = (Button) cptPause;
        }
        Component cptPrevious = controllerLayout.findComponentById(ResourceTable.Id_btn_previous);
        if (cptPrevious instanceof Button) {
            btnPrevious = (Button) cptPrevious;
        }
        Component cptNext = controllerLayout.findComponentById(ResourceTable.Id_btn_next);
        if (cptNext instanceof Button) {
            btnNext = (Button) cptNext;
        }
        Component cptTitle = controllerLayout.findComponentById(ResourceTable.Id_text_title);
        if (cptTitle instanceof Text) {
            textTitle = (Text) cptTitle;
        }
        Component cptPosition = controllerLayout.findComponentById(ResourceTable.Id_text_position);
        if (cptPosition instanceof Text) {
            textPosition = (Text) cptPosition;
        }
        Component cptDuration = controllerLayout.findComponentById(ResourceTable.Id_text_duration);
        if (cptDuration instanceof Text) {
            textDuration = (Text) cptDuration;
        }

        btnPlay.setClickedListener(c -> {
            mPlayer.play();
        });
        btnPause.setClickedListener(c -> {
            mPlayer.pause();
        });
        btnNext.setClickedListener(c -> {
            // 下一首
            if (playIndex < playList.size() -1) {
                playIndex++;
                mPlayer.stop();
            } else {
                playIndex = 0;
            }
            HiLog.info(LABEL, "setClickedListener: " + playList.size() + "");

            mPlayer.open(playList.get(playIndex));
            mPlayer.play();
        });
    }

    // 实现StatusChangeListener接口， 并new一个实例
    // 在MPlayer中进行回调
    public StatusChangeListener statusChangeListener = new StatusChangeListener() {
        @Override
        public void callback(PlayerStatus status) {
            onStatusChanged(status);
        }
    };

    // 播放状态改变时调用
    private void onStatusChanged(PlayerStatus playerStatus) {
        switch (playerStatus) {
            case PREPARE: {
                this.context.getUITaskDispatcher().syncDispatch(new Runnable() {
                    @Override
                    public void run() {
                        if (progress != null) {
                            progress.setMaxValue(mPlayer.getDuration());
                        }
                        // 显示播放按钮
                        textDuration.setText(mPlayer.getPlayerDurationTimer());
                        showPlayPause(true);
                        textTitle.setText(mPlayer.getTitle());
                    }
                });
                break;
            }
            case PLAY: {
                // 播放时，显示暂停按钮
                showPlayPause(false);
                // 将事件id发送到事件队列
                controllerHandler.sendEvent(Constants.PLAYER_PROGRESS_RUNNING);
                break;
            }
            case PAUSE: {
                // 暂停时显示播放按钮
                showPlayPause(true);
                controllerHandler.removeEvent(Constants.PLAYER_PROGRESS_RUNNING);
                break;
            }
            case STOP: {
                controllerHandler.removeEvent(Constants.PLAYER_PROGRESS_RUNNING);
                break;
            }
            case COMPLETE: {
                // 显示播放按钮
                showPlayPause(true);
                controllerHandler.removeEvent(Constants.PLAYER_PROGRESS_RUNNING);
                break;
            }
        }
    }

    private void showPlayPause(boolean v) {
        this.context.getUITaskDispatcher().delayDispatch(new Runnable() {
            @Override
            public void run() {
                if (v) {
                    // 显示播放按钮，隐藏暂停按钮
                    btnPlay.setVisibility(VISIBLE);
                    btnPause.setVisibility(INVISIBLE);
                } else {
                    btnPlay.setVisibility(INVISIBLE);
                    btnPause.setVisibility(VISIBLE);

                }
            }
        }, 0);
    }
    private void createHandler() {
        // create(inNewThread): 创建一个线程并启动一个带有inNewThread参数的EventRunner，该参数用于指定谁将管理EventRunner。
        // inNewThread: 指定系统是否自动管理EventRunner。取值为true表示由系统自动管理，取值为false表示由用户手工管理。
        EventRunner eventRunner = EventRunner.create(true);
        if (eventRunner == null) {
            return;
        }
        controllerHandler = new ControllerHandler(eventRunner);
    }

    /**
     * 每个EventHandler实例都绑定到一个线程
     */
    private class ControllerHandler extends EventHandler {
        public ControllerHandler(EventRunner runner) {
            super(runner);
        }

        /**
         * 需要覆盖 processEvent 方法
         * @param event
         */
        @Override
        protected void processEvent(InnerEvent event) {
            super.processEvent(event);
            if (event == null) {
                return;
            }
            switch (event.eventId) {
                case Constants.PLAYER_PROGRESS_RUNNING: {
                    // 设置进度条
                    // 在UI的主线程延时0秒执行
                    context.getUITaskDispatcher().delayDispatch(new Runnable() {
                        @Override
                        public void run() {
                            if (progress != null) {
                                progress.setProgressValue(mPlayer.getPosition());
                                textPosition.setText(mPlayer.getPlayerCurrentTime());
                            }
                        }
                    }, 0);
                    // 将具有指定优先级的延迟事件发送到事件队列
                    controllerHandler.sendEvent(Constants.PLAYER_PROGRESS_RUNNING,
                            Constants.PROGRESS_RUNNING_TIME, Priority.IMMEDIATE
                    );
                    break;
                }
            }
        }
    }

    public Component.ClickedListener mClickedListener = new Component.ClickedListener() {
        @Override
        public void onClick(Component component) {
            int componentId = component.getId();
            switch (componentId) {
                case BUTTON_PLAY_ID: {
                    mPlayer.open();
                }
            }
        }
    };
}
